package app

import (
	"context"
	"fmt"
	"time"

	"charging_pile/common/globalkey"
	"charging_pile/common/token"
	"charging_pile/common/xerr"
	"charging_pile/models"
	"charging_pile/user/internal/svc"
	"charging_pile/user/internal/types"

	"github.com/pkg/errors"
	"github.com/zeromicro/go-zero/core/logx"
)

type UserLoginOrRegisterLogic struct {
	logx.Logger
	ctx    context.Context
	svcCtx *svc.ServiceContext
}

func NewUserLoginOrRegisterLogic(ctx context.Context, svcCtx *svc.ServiceContext) *UserLoginOrRegisterLogic {
	return &UserLoginOrRegisterLogic{
		Logger: logx.WithContext(ctx),
		ctx:    ctx,
		svcCtx: svcCtx,
	}
}

func (l *UserLoginOrRegisterLogic) UserLoginOrRegister(req *types.LoginInfo) (resp *types.UserInfo, err error) {
	key := fmt.Sprintf(globalkey.PhoneCodeAuth, req.Appid, req.Phone)
	code, err := l.svcCtx.RedisObj.GetCtx(l.ctx, key)

	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.CACHE_ERR), "获取验证码失败:%s", code)
	}

	if code != req.ValidateCode {
		l.svcCtx.RedisObj.DelCtx(l.ctx, key)
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.CACHE_ERR), "验证阿门校验失败:%s,%s", code, req.ValidateCode)
	}

	user, err := l.svcCtx.Models.User.FindOneByAppidPhone(l.ctx, req.Appid, req.Phone)
	if models.HasError(err) {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "查找用户输出库出错%s %s", req.Appid, req.Phone)
	}

	if user == nil {
		user = &models.User{
			Nickname: req.Phone[7:],
			Avatar:   "",
			Phone:    req.Phone,
			Appid:    req.Appid,
			DelState: 0,
			Version:  0,
		}
		res, err := l.svcCtx.Models.User.Insert(l.ctx, nil, user)
		if models.HasError(err) {
			return nil, errors.Wrapf(xerr.NewErrCode(xerr.DB_ERROR), "创建用户出错%s %s", req.Appid, req.Phone)
		}
		id, _ := res.LastInsertId()
		user.Id = id
	}

	j := l.svcCtx.Config.JwtAuth
	tk, err := token.GetTokenStr(j.AccessSecret, time.Now().Unix(), j.AccessExpire, user.Id)
	if err != nil {
		return nil, errors.Wrapf(xerr.NewErrCode(xerr.TOKEN_GENERATE_ERROR), "生产token 失败%+v", err)
	}

	resp = &types.UserInfo{
		Name:             user.Nickname,
		CarType:          "",
		Carnum:           "",
		Phone:            user.Phone,
		Appid:            user.Appid,
		Wallet:           types.Wallet{},
		Vip:              types.Vip{},
		UnfinishedOrders: []types.Order{},
		Token:            tk,
	}

	return resp, nil
}
